import {
  ElButton,
  ElCol,
  ElDialog,
  ElForm,
  ElFormItem,
  ElInput,
  ElOption,
  ElRadio,
  ElRadioGroup,
  ElRow,
  ElSelect,
  ElSpace,
  ElTreeSelect,
  type FormInstance,
  type FormRules
} from 'element-plus'
import { isEmpty } from 'lodash-unified'
import { computed, defineComponent, reactive, toRefs } from 'vue'

import { type IUserPageItem, userApi } from '@/apis'
import { dictToOptions, objAssign } from '@/utils'

import { formData, type IFormData, userDialogProps } from './UserDialog.define'

export default defineComponent({
  name: 'UserDialog',
  props: userDialogProps(),
  emits: ['success'],
  setup(_, { emit }) {
    const state = reactive({
      show: false,
      formRef: {} as FormInstance,
      formModel: formData(),
      formRules: {
        nickName: [{ required: true, message: '用户昵称不能为空' }],
        userName: [{ required: true, message: '用户名称不能为空' }],
        password: [{ required: true, message: '用户密码不能为空' }]
      } as FormRules<IFormData>,
      postOptions: [] as OptionItem[],
      roleOptions: [] as OptionItem[],
      selectedRecord: {} as IUserPageItem,
      submitLoading: false
    })

    const isAdd = computed(() => isEmpty(state.selectedRecord))

    const dialogTitle = computed(() =>
      isAdd.value ? '添加用户数据' : '修改用户数据'
    )

    async function open(data = {} as IUserPageItem) {
      objAssign(state.formModel, data)
      state.selectedRecord = data
      state.show = true

      getFormData(data.id)
    }

    async function getFormData(id?: string) {
      const { posts, roles, postIds, roleIds } = id
        ? await userApi.getUserEditFormData(id)
        : await userApi.getUserAddFormData()

      state.postOptions = dictToOptions(posts, {
        labelKey: 'postName',
        valueKey: 'id'
      })
      state.roleOptions = dictToOptions(roles, {
        labelKey: 'roleName',
        valueKey: 'id'
      })

      if (id) {
        objAssign(state.formModel, { postIds, roleIds })
      }
    }

    function handleClose() {
      state.show = false
      state.submitLoading = false
      state.selectedRecord = Object.create(null)
      state.formModel = formData()
      state.formRef.clearValidate()
    }

    function handleSubmit() {
      state.formRef.validate(async valid => {
        if (valid) {
          try {
            state.submitLoading = true

            if (isAdd.value) {
              await userApi.createUser(state.formModel)
            } else {
              await userApi.updateUser(state.selectedRecord.id, state.formModel)
            }

            handleClose()
            emit('success')
          } catch (error) {
            state.submitLoading = false
          }
        }
      })
    }

    return {
      ...toRefs(state),
      isAdd,
      dialogTitle,
      open,
      handleClose,
      handleSubmit
    }
  },
  render() {
    return (
      <ElDialog
        v-model={this.show}
        title={this.dialogTitle}
        beforeClose={this.handleClose}
        width="600px"
        destroyOnClose
      >
        {{
          default: () => (
            <ElForm
              ref={(e: any) => (this.formRef = e)}
              model={this.formModel}
              rules={this.formRules}
              labelWidth="100px"
            >
              <ElRow>
                <ElCol span={12}>
                  <ElFormItem label="用户昵称" prop="nickName">
                    <ElInput
                      v-model={this.formModel.nickName}
                      placeholder="请输入用户昵称"
                    />
                  </ElFormItem>
                </ElCol>
                <ElCol span={12}>
                  <ElFormItem label="归属部门" prop="deptId">
                    <ElTreeSelect
                      v-model={this.formModel.deptId}
                      data={this.deptTreeData}
                      nodeKey="key"
                      props={{
                        children: 'children',
                        label: 'title'
                      }}
                      clearable
                      checkStrictly
                      placeholder="请选择归属部门"
                    />
                  </ElFormItem>
                </ElCol>
              </ElRow>
              <ElRow>
                <ElCol span={12}>
                  <ElFormItem label="手机号码" prop="phone">
                    <ElInput
                      v-model={this.formModel.phone}
                      placeholder="请输入手机号码"
                    />
                  </ElFormItem>
                </ElCol>
                <ElCol span={12}>
                  <ElFormItem label="邮箱" prop="email">
                    <ElInput
                      v-model={this.formModel.email}
                      placeholder="请输入邮箱"
                    />
                  </ElFormItem>
                </ElCol>
              </ElRow>
              <ElRow>
                <ElCol span={12}>
                  <ElFormItem label="用户名称" prop="userName">
                    <ElInput
                      v-model={this.formModel.userName}
                      disabled={!this.isAdd}
                      placeholder="请输入用户名称"
                    />
                  </ElFormItem>
                </ElCol>
                <ElCol span={12}>
                  <ElFormItem label="用户密码" prop="password">
                    <ElInput
                      v-model={this.formModel.password}
                      type="password"
                      disabled={!this.isAdd}
                      placeholder="请输入用户密码"
                    />
                  </ElFormItem>
                </ElCol>
              </ElRow>
              <ElRow>
                <ElCol span={12}>
                  <ElFormItem label="用户性别" prop="sex">
                    <ElSelect
                      v-model={this.formModel.sex}
                      placeholder="请选择性别"
                    >
                      {this.sexOptions.map(v => (
                        <ElOption
                          key={v.value}
                          value={v.value}
                          label={v.label}
                        />
                      ))}
                    </ElSelect>
                  </ElFormItem>
                </ElCol>
                <ElCol span={12}>
                  <ElFormItem label="状态" prop="status">
                    <ElRadioGroup v-model={this.formModel.status}>
                      {this.statusOptions.map(v => (
                        <ElRadio key={v.value} value={v.value}>
                          {v.label}
                        </ElRadio>
                      ))}
                    </ElRadioGroup>
                  </ElFormItem>
                </ElCol>
              </ElRow>
              <ElRow>
                <ElCol span={12}>
                  <ElFormItem label="岗位" prop="postIds">
                    <ElSelect
                      v-model={this.formModel.postIds}
                      multiple
                      collapseTags
                      placeholder="请选择岗位"
                    >
                      {this.postOptions.map(v => (
                        <ElOption
                          key={v.value}
                          value={v.value}
                          label={v.label}
                        />
                      ))}
                    </ElSelect>
                  </ElFormItem>
                </ElCol>
                <ElCol span={12}>
                  <ElFormItem label="角色" prop="roleIds">
                    <ElSelect
                      v-model={this.formModel.roleIds}
                      multiple
                      collapseTags
                      placeholder="请选择角色"
                    >
                      {this.roleOptions.map(v => (
                        <ElOption
                          key={v.value}
                          value={v.value}
                          label={v.label}
                        />
                      ))}
                    </ElSelect>
                  </ElFormItem>
                </ElCol>
              </ElRow>
              <ElFormItem label="备注" prop="remark">
                <ElInput
                  v-model={this.formModel.remark}
                  type="textarea"
                  rows={3}
                  placeholder="请输入内容"
                />
              </ElFormItem>
            </ElForm>
          ),
          footer: () => (
            <ElSpace>
              <ElButton onClick={this.handleClose}>取消</ElButton>
              <ElButton
                type="primary"
                loading={this.submitLoading}
                onClick={this.handleSubmit}
              >
                确定
              </ElButton>
            </ElSpace>
          )
        }}
      </ElDialog>
    )
  }
})
